home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / PB_212.ZIP / _GRAPH.CPP next >
C/C++ Source or Header  |  1995-09-09  |  16KB  |  622 lines

  1. /***************************************************************************/
  2. /*** _GRAPH.CPP                    Usage graph module for ProBoard v2.10 ***/
  3. /*** ─────────────────────────────────────────────────────────────────── ***/
  4. /*** This source file is distributed together with ProBoard v2.10, and   ***/
  5. /*** may be modified and redistributed, provided that this header is     ***/
  6. /*** not modified. When distributing the modified source code, make sure ***/
  7. /*** you add a comment block with your name and any changes you have     ***/
  8. /*** made. It would be appreciated if you send a copy of the modified    ***/
  9. /*** source code to the author (Philippe Leybaert)                       ***/
  10. /***                                                                     ***/
  11. /*** The author can be reached at FidoNet 2:291/1905                     ***/
  12. /***                           or CompuServe 70314,2021                  ***/
  13. /***                           or phl@innet.be                           ***/
  14. /***                           or in the FidoNet PROBOARD echo           ***/
  15. /***************************************************************************/
  16.  
  17. #include <pb_sdk.h>
  18. #include "cppdate.hpp"
  19.  
  20. #define GRAPH_SPEED     0
  21. #define GRAPH_LASTDAYS  1
  22. #define GRAPH_HOURLY    2
  23. #define GRAPH_WEEKS     3
  24. #define GRAPH_AVGSPEED  4
  25.  
  26. void put_meganum( word num );
  27.  
  28. long num_calls;
  29.  
  30. char *weekdays[] = { "Mo" , "Tu" , "We" , "Th" , "Fr" , "Sa" , "Su" };
  31.  
  32. int
  33. read_binlog(int mode,int ndays,long *data)
  34. {
  35.     FILE *fp;
  36.     BINLOG bl;
  37.     Date today(TODAY);
  38.     char fname[80];
  39.     int max_diff = 0;
  40.     int i;
  41.     long total = 0;
  42.  
  43.     long count[24];
  44.  
  45.     for(i = 0;i<24;i++) count[i] = 0;
  46.  
  47.     printf("\n\7\f\nReading data...");
  48.  
  49.     strcpy(fname,SysPath);
  50.     strcat(fname,"BINLOG.PB");
  51.  
  52.     fp = fopen(fname,"rb");
  53.  
  54.     if(fp == NULL)
  55.     {
  56.         Log(LOG_FRIEND,"Unable to open BINLOG.PB");
  57.  
  58.         return -1;
  59.     }
  60.  
  61.     setvbuf(fp,NULL,_IOFBF,16384);
  62.  
  63.     for(;;)
  64.     {
  65.         if(fread( &bl , sizeof(bl) , 1 , fp) != 1) break;
  66.  
  67.         Date bl_date(bl.date[0],bl.date[1],bl.date[2]);
  68.  
  69.         if(bl.timeIn[0] > 23 || !bl_date.ok())
  70.         {
  71.             Log(LOG_FRIEND,"BINLOG.PB corrupted!");
  72.  
  73.             fclose(fp);
  74.  
  75.             return -1;
  76.         }
  77.  
  78.         if(!bl.baud) continue;
  79.  
  80.         switch(mode)
  81.         {
  82.             case GRAPH_HOURLY:
  83.             {
  84.                 int h;
  85.                 int onlinetime;
  86.                 int diff = int(today - bl_date);
  87.  
  88.                 if(ndays && diff > ndays) continue;
  89.  
  90.                 num_calls++;
  91.  
  92.                 if(diff > max_diff) max_diff = diff;
  93.  
  94.  
  95.                 onlinetime = 60 * (bl.timeOut[0] - bl.timeIn[0])
  96.                                 + (bl.timeOut[1] - bl.timeIn[1]);
  97.  
  98.                 if(onlinetime < 0) onlinetime += 60*24;
  99.  
  100.                 h = bl.timeIn[0] - 6;
  101.  
  102.                 if(h < 0) h += 24;
  103.  
  104.                 data[h] += onlinetime;
  105.             }
  106.             break;
  107.  
  108.             case GRAPH_LASTDAYS:
  109.             {
  110.                 int diff = int(today - bl_date);
  111.  
  112.                 if(diff < 24 && diff >= 0)
  113.                 {
  114.                     int onlinetime = 60 * (bl.timeOut[0] - bl.timeIn[0])
  115.                                         + (bl.timeOut[1] - bl.timeIn[1]);
  116.  
  117.                     num_calls++;
  118.  
  119.                     if(onlinetime < 0) onlinetime += 60*24;
  120.  
  121.                     data[23-diff] += onlinetime;
  122.  
  123.                     if(diff > max_diff) max_diff = diff;
  124.                 }
  125.             }
  126.             break;
  127.  
  128.             case GRAPH_WEEKS:
  129.             {
  130.                 int week         = bl_date.weekNum();
  131.                 int weeks_to_add = today.weeksInYear(today.year()-1);
  132.                 int weeknow      = today.weekNum() + weeks_to_add;
  133.  
  134.                 int diff = int(today - bl_date);
  135.  
  136.                 if(diff < 0  ||  diff > 200) continue;
  137.  
  138.                 if(week+weeks_to_add <= weeknow) week += weeks_to_add;
  139.  
  140.                 if(weeknow-week < 24)
  141.                 {
  142.                     int onlinetime = 60 * (bl.timeOut[0] - bl.timeIn[0])
  143.                                         + (bl.timeOut[1] - bl.timeIn[1]);
  144.  
  145.                     if(onlinetime < 0) onlinetime += 60*24;
  146.  
  147.                     data[23 - (weeknow - week)] += onlinetime;
  148.  
  149.                     if(weeknow - week > max_diff) max_diff = weeknow - week;
  150.  
  151.                     num_calls++;
  152.                 }
  153.             }
  154.             break;
  155.  
  156.             case GRAPH_SPEED:
  157.             {
  158.                 int speed;
  159.                 int diff = int(today - bl_date);
  160.  
  161.                 if(!bl.baud) continue;
  162.  
  163.                 if(ndays && diff > ndays) continue;
  164.  
  165.                 num_calls++;
  166.  
  167.                 if(diff > max_diff) max_diff = diff;
  168.  
  169.                 switch(bl.baud)
  170.                 {
  171.                     case 2400L : speed =  0;  break;
  172.                     case 9600L : speed =  1;  break;
  173.                     case 14400L: speed =  2;  break;
  174.                     case 16800L: speed =  3;  break;
  175.                     case 19200L: speed =  4;  break;
  176.                     case 21600L: speed =  5;  break;
  177.                     case 24000L: speed =  6;  break;
  178.                     case 26400L: speed =  7;  break;
  179.                     case 28800L: speed =  8;  break;
  180.                     case 31200L: speed =  9;  break;
  181.                     case 33600L: speed = 10; break;
  182.                     default    : speed = 11;  break;
  183.                 }
  184.  
  185.                 data[speed]++;
  186.                 total++;
  187.             }
  188.             break;
  189.  
  190.             case GRAPH_AVGSPEED:
  191.             {
  192.                 int week         = bl_date.weekNum();
  193.                 int weeks_to_add = today.weeksInYear(today.year()-1);
  194.                 int weeknow      = today.weekNum() + weeks_to_add;
  195.  
  196.                 if(int(today - bl_date) < 0) continue;
  197.  
  198.                 if(week+weeks_to_add <= weeknow) week += weeks_to_add;
  199.  
  200.                 if(weeknow-week < 24)
  201.                 {
  202.                     count[23 - (weeknow - week)] ++;
  203.  
  204.                     data[23 - (weeknow - week)] += l_div(bl.baud ,100);
  205.  
  206.                     if(weeknow - week > max_diff) max_diff = weeknow - week;
  207.  
  208.                     num_calls++;
  209.                 }
  210.             }
  211.             break;
  212.         }
  213.     }
  214.  
  215.     switch(mode)
  216.     {
  217.         case GRAPH_HOURLY:
  218.         {
  219.             if(max_diff) for(i=0;i<24;i++) data[i] = l_div(l_mul(data[i],10) , (6 * max_diff));
  220.         }
  221.         break;
  222.  
  223.         case GRAPH_LASTDAYS:
  224.         {
  225.             for(i = 0 ; i < 24 ; i++) data[i] = l_div(l_mul(data[i] , 10) , 144);
  226.         }
  227.         break;
  228.  
  229.         case GRAPH_SPEED:
  230.         {
  231.             if(total) for(i = 0 ; i < 24 ; i++) data[i] = l_div(l_mul(data[i] , 100) , total);
  232.         }
  233.         break;
  234.  
  235.         case GRAPH_WEEKS:
  236.         {
  237.             for(i = 0 ; i < 24 ; i++) data[i] = l_div(l_mul(data[i] , 10) , 1008);
  238.         }
  239.         break;
  240.  
  241.         case GRAPH_AVGSPEED:
  242.         {
  243.             for(i = 0 ; i < 24 ; i++) if(count[i]) data[i] = l_div(data[i] , count[i]);
  244.         }
  245.     }
  246.  
  247.     fclose(fp);
  248.  
  249.     if(max_diff < 0)
  250.     {
  251.         printf("\1Error reading log file! Please inform sysop!\n\n"
  252.                "\7Press \3[Enter]\7 to continue.\t");
  253.     }
  254.     else
  255.     {
  256.         printf("\n");
  257.     }
  258.  
  259.     return max_diff;
  260. }
  261.  
  262. static void
  263. chart(long *data,int data_size,int width,char *str1,char *str2,char *str3)
  264. {
  265.     static long legal_max[] = { 4,8,12,20,40,60,80,100,120,160,200,240,300,500,0 };
  266.     long max = 0;
  267.     int i;
  268.  
  269.    for(i = 0 ; i < data_size ; i++) if(data[i] > max) max = data[i];
  270.  
  271.    for(i = 0 ; legal_max[i] ; i++)
  272.       if(max <= legal_max[i])
  273.          break;
  274.  
  275.    if(legal_max[i]) max = legal_max[i];
  276.  
  277.    if(RIP())
  278.    {
  279.       DisableStop();
  280.       LocalDisplay(FALSE);
  281.  
  282.       printf("!|1K|*|w0000000000|W00|Y00000100|1B00000200LK040F000B010900000F07000000\n");
  283.       printf("!|1U0A08H8880000<><>|1B000002007S040F000B010900000F07000000\n");
  284.       printf("!|1U0U0OGO1C0000<>\\\n");
  285.       printf("%s\\\n",str1);
  286.       printf("<>\n");
  287.       printf("!|1B000002007K040F000B010900000F07000000|1U0U1KGO7S0000<><>|c0F|=00000003\n");
  288.       printf("!|LGE741474|L2874281S|Y02000400|1B00000200LC020F000F080700000F07000000\n");
  289.  
  290.       printf("!|=00000001\n");
  291.  
  292.       for(i=0;i<4;i++)
  293.       {
  294.          printf("!|c01|L");
  295.          put_meganum(90);
  296.          put_meganum(70 + i*45);
  297.          put_meganum(570);
  298.          put_meganum(70 + i*45);
  299.  
  300.          printf("\n!|c0E|@15");
  301.          put_meganum(70 + i*45 - 5);
  302.          printf("%5d\n",max - (max/4) * i);
  303.       }
  304.  
  305.       printf("!|c0F\n");
  306.  
  307.       for(i=0;i<data_size;i++)
  308.       {
  309.          if(!data[i]) continue;
  310.  
  311.          printf("!|1U");
  312.          put_meganum(90 + i * width * 6);
  313.          put_meganum(250 - 180L*data[i] / max);
  314.          put_meganum(90 + (i+1) * width * 6 - 6);
  315.          put_meganum(250);
  316.          printf("0000<><>\n");
  317.       }
  318.  
  319.       printf("!|@2H79%s\n" , str3);
  320.       printf("!|w0012271510|#|#|#\n");
  321.  
  322.       LocalDisplay(TRUE);
  323.       RemoteDisplay(FALSE);
  324.    }
  325.  
  326.    EnableStop();
  327.  
  328.    printf("\n\f\6 %-3s\7║\6 %s\n" , str2, str1);
  329.  
  330.    if(Stopped()) return;
  331.  
  332.    printf("\7════╬═════════════════════════════════════════════════════════════════════════╗\n");
  333.  
  334.    if(Stopped()) return;
  335.  
  336.    for(i = 0 ; i < 16 ; i++)
  337.    {
  338.       int y;
  339.  
  340.       if(!(i%4)) printf("\1%3d\7 ║",(16-i) * (int)max / 16);
  341.                else printf("    \7║\3");
  342.  
  343.       if(!(i%4)) SetFullColor(7);
  344.  
  345.       if(Stopped()) return;
  346.  
  347.       for(y=0 ; y<data_size ; y++)
  348.       {
  349.             int w;
  350.  
  351.             putchar( !(i%4) ? '─' : ' ');
  352.  
  353.             if(data[y] >= l_div(l_mul(max,16-i),16) && data[y])
  354.             {
  355.                if(!(i%4)) SetColor(3);
  356.                for(w = 1 ; w < width ; w++) putchar('█');
  357.                if(!(i%4)) SetFullColor(7);
  358.             }
  359.             else
  360.             if(data[y] >= l_div(l_mul(max,31-2*i),32) && data[y])
  361.             {
  362.                if(!(i%4)) SetColor(3);
  363.                for(w = 1 ; w < width ; w++) putchar('▄');
  364.                if(!(i%4)) SetFullColor(7);
  365.             }
  366.             else
  367.             {
  368.                for(w = 1 ; w < width ; w++) putchar(!(i%4) ? '─' : ' ');
  369.             }
  370.  
  371.             if(Stopped()) return;
  372.       }
  373.  
  374.       for(int w=72;w>=(data_size*width);w--)
  375.          putchar(!(i%4) ? '─' : ' ');
  376.  
  377.       printf("\7║\n");
  378.  
  379.       if(Stopped()) return;
  380.    }
  381.  
  382.    printf("\7════╬═════════════════════════════════════════════════════════════════════════╣\n"
  383.             "    ║\6 %-72.72s\7║\n",str3);
  384.  
  385.    RemoteDisplay(TRUE);
  386.  
  387.    printf("\n\7Press \3[Enter]\7 to continue.\t");
  388.  
  389.    if(RIP()) printf("\n!|1K|*\n");
  390. }
  391.  
  392. void
  393. last_days(int ndays,char *msg)
  394. {
  395.     int i;
  396.  
  397.     long *data = (long *)malloc( 24 * sizeof(long) );
  398.  
  399.     for(i = 0 ; i < 24 ; i++) data[i] = 0;
  400.  
  401.     if(read_binlog(GRAPH_LASTDAYS,ndays,data) >= 1)
  402.     {
  403.         char *p;
  404.         int wd;
  405.         Date today(TODAY);
  406.         char str[80];
  407.  
  408.         wd = today.weekDay() - 2;
  409.  
  410.         str[0] = 0;
  411.  
  412.         for(i = 0 ; i < 24 ;wd++,i++)
  413.         {
  414.             if(wd > 6) wd -= 7;
  415.             if(wd < 0) wd += 7;
  416.  
  417.             strcat(str , weekdays[wd]);
  418.             strcat(str," ");
  419.         }
  420.  
  421.         p = msg;
  422.  
  423.         if(p[0] == '\0') p = "Usage graph per day for the last %d days";
  424.  
  425.         chart(data,24,3,form(p,24),"%",str);
  426.     }
  427.  
  428.     free(data);
  429. }
  430.  
  431. void
  432. speed_graph(int numdays , char *msg)
  433. {
  434.     int i;
  435.  
  436.     long *data = (long *)malloc( 24 * sizeof(long));
  437.  
  438.     for(i = 0 ; i < 24 ; i++) data[i] = 0;
  439.  
  440.     numdays = read_binlog(GRAPH_SPEED,numdays,data);
  441.  
  442.     if(numdays >= 1)
  443.     {
  444.         char *p = msg;
  445.  
  446.         if(p[0] == '\0') p = "Speed Statistics for the last %d days";
  447.  
  448.         chart(data,12,6,form(p,numdays),"%"," 2400  9600 14400 16800 19200 21600 24000 26400 28800 31200 33600 Other");
  449.     }
  450.  
  451.     free(data);
  452. }
  453.  
  454. void
  455. avgspeed_graph(int nweeks,char *msg)
  456. {
  457.     int i;
  458.  
  459.     long *data = (long *)malloc( 24 * sizeof(long));
  460.  
  461.     for(i = 0 ; i < 24 ; i++) data[i] = 0;
  462.  
  463.     nweeks = read_binlog(GRAPH_AVGSPEED,24,data);
  464.  
  465.     if(nweeks >= 1)
  466.     {
  467.         int weeknr;
  468.         char *p;
  469.         Date today(TODAY);
  470.         char str[80];
  471.  
  472.         weeknr = today.weekNum() + 53 - 24;
  473.  
  474.         str[0] = '\0';
  475.  
  476.         for(i = weeknr ; i < (weeknr+24) ; i++)
  477.            strcat(str,form("%02d ",(i%53)+1));
  478.  
  479.         p = msg;
  480.  
  481.         if(p[0] == '\0') p = "Average connect speed for the last %d weeks";
  482.  
  483.         chart(data,24,3,form(p,nweeks),"BPS",str);
  484.     }
  485.  
  486.     free(data);
  487. }
  488.  
  489.  
  490. void
  491. hourly_graph(int numdays,char *msg)
  492. {
  493.     int i;
  494.  
  495.     long *data = (long *)malloc( 24 * sizeof(long));
  496.  
  497.     for(i=0;i<24;i++) data[i] = 0;
  498.  
  499.     num_calls = 0;
  500.  
  501.     numdays = read_binlog(GRAPH_HOURLY , numdays , data);
  502.  
  503.     if(numdays >= 1)
  504.     {
  505.         char *p = msg;
  506.  
  507.         if(p[0] == '\0') p = "Hourly Usage Graph for the last %d days (%d.%d calls/day)";
  508.  
  509.         chart(data,24,3,form(p,numdays,(int)l_div(num_calls,numdays),int(l_div(l_mul(num_calls,10),numdays))%10),"%","06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 00 01 02 03 04 05");
  510.     }
  511.  
  512.     free(data);
  513. }
  514.  
  515. void
  516. weekly_graph(int nweeks,char *msg)
  517. {
  518.     int i;
  519.  
  520.     long *data = (long *)malloc( 24 * sizeof(long));
  521.  
  522.     for(i = 0 ; i < 24 ; i++) data[i] = 0;
  523.  
  524.     nweeks = read_binlog(GRAPH_WEEKS,24,data);
  525.  
  526.     if(nweeks >= 1)
  527.     {
  528.         int weeknr;
  529.         char *p;
  530.         Date today(TODAY);
  531.         char str[80];
  532.  
  533.         nweeks++;
  534.  
  535.         weeknr = today.weekNum() + 53 - 24;
  536.  
  537.         str[0] = '\0';
  538.  
  539.         for(i = weeknr ; i < (weeknr+24) ; i++)
  540.            strcat(str,form("%02d ",(i%53)+1));
  541.  
  542.         p = msg;
  543.  
  544.         if(p[0] == '\0') p = "Usage graph per week for the last %d weeks";
  545.  
  546.         chart(data,24,3,form(p,nweeks),"%",str);
  547.     }
  548.  
  549.     free(data);
  550. }
  551.  
  552.  
  553.  
  554. void
  555. main(int argc,char *argv[])
  556. {
  557.     int report = 0;
  558.     int i;
  559.     int ndays = 0;
  560.  
  561.     char text[80];
  562.  
  563.     text[0] = 0;
  564.  
  565.     for(i=1;i<argc;i++)
  566.     {
  567.         if(isalpha(argv[i][0]))
  568.         {
  569.             if(!stricmp(argv[i] , "Speed"   )) report = 0;
  570.             if(!stricmp(argv[i] , "LastDays")) report = 1;
  571.             if(!stricmp(argv[i] , "Hourly"  )) report = 2;
  572.             if(!stricmp(argv[i] , "Weekly"  )) report = 3;
  573.             if(!stricmp(argv[i] , "AvgSpeed")) report = 4;
  574.         }
  575.  
  576.         if(argv[i][0] == '/')
  577.         {
  578.             switch(argv[i][1])
  579.             {
  580.                 case 'N': ndays = atoi(&argv[i][3]);
  581.                           break;
  582.                 case 'T': strcpy(text,&argv[i][3]);
  583.                           break;
  584.             }
  585.         }
  586.     }
  587.  
  588.     switch(report)
  589.     {
  590.         case 0: speed_graph(ndays,text);
  591.                 break;
  592.         case 1: last_days(ndays,text);
  593.                 break;
  594.         case 2: hourly_graph(ndays,text);
  595.                 break;
  596.         case 3: weekly_graph(ndays,text);
  597.                 break;
  598.         case 4: avgspeed_graph(ndays,text);
  599.                 break;
  600.     }
  601. }
  602.  
  603. void
  604. put_meganum( word num )
  605. {
  606.    int n[2];
  607.    char s[3] = "00";
  608.  
  609.    n[0] = num / 36;
  610.    n[1] = num % 36;
  611.  
  612.    for(int i = 0 ; i < 2 ; i++)
  613.    {
  614.       if(n[i] < 10)
  615.          s[i] = '0' + n[i];
  616.       else
  617.          s[i] = 'A' + n[i] - 10;
  618.    }
  619.  
  620.    printf(s);
  621. }
  622.